/**
 ********************************************************************
 * @author roocket
 * @file    queue.c
 * @version V0.0.0
 * @date    2024/3/22
 * @brief   This file is to indicate queue functions. 
 * @attention Code file rules:
 * rule: file encoding use UTF8;
 * rule: max line length 120 characters;
 * rule: line separator \r\n;
 * rule: use clion auto code format tool.
 */
#include "queue.h"

int queue_valid_inner_data(struct msqid_ds *mss, struct queue_setting *setting)
{   
    int err = -1;

    err = msgctl(setting->id, IPC_STAT, mss);
    if (-1 == err) { 
        perror("msgctl");
        return -1;
    }
    return 0;
}

int queue_set_data(const void *msg, unsigned int len, struct queue_setting *setting)
{
    struct queue q;
    memset(&q,0,sizeof(struct queue));

    /* validate len */
    if (!len || len >= MAX_TEXT_LEN) {
        perror("max length");
        return -1;
    }

    //set mtype should be 'must be'
    q.mtype     = setting->mtype;
    q.qdata.len = len;
    memcpy(q.qdata.mtext, msg, len);

    /* set IPC_NOWAIT  always return */
    if (msgsnd(setting->id, (void *)&q, sizeof(q.qdata), setting->snd_mode) < 0) {
        perror("msgsnd data");
        return -1;
    }
    return 0;
}

int queue_get_data(struct queue *q, struct queue_setting *setting)
{
    int ret = -1;

    ret = msgrcv(setting->id, (void *)q, MAX_QUEUE_LEN, setting->mtype, IPC_NOWAIT);
    if (-1 == ret) {
        perror("receive msg error");
        return -1;
    }

    if (!q->qdata.len) {
        perror("qdata len error");
        return -1;
    }
    return 0;
}

int queue_init(struct queue_setting *setting)
{
    int id = -1;
    int ret = -1;

    key_t key = ftok(setting->key_string, setting->flag);

    id = msgget(key, IPC_CREAT | 0666);
    if (-1 == id) {
        perror("msgget data 1");
        return -1;
    }

    /* remove queue */
    ret = msgctl(id, IPC_RMID, NULL);
    if (-1 == ret) {
        perror("msgctl cmd");
        return -1;
    }

    /* reset queue */
    id = msgget(key, IPC_CREAT | 0666);
    if(-1 == id) {
        perror("msgget data 2");
        return -1;
    }

    /*set qsetting*/
    setting->id = id;
    return 0;
}
